home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 051-075 / 061 / microemacs / termio.c < prev    next >
C/C++ Source or Header  |  1995-03-13  |  13KB  |  467 lines

  1. /*
  2.  * The functions in this file negotiate with the operating system for
  3.  * characters, and write characters in a barely buffered fashion on the display.
  4.  * All operating systems.
  5.  */
  6. #include        <stdio.h>
  7. #include    "estruct.h"
  8. #include        "edef.h"
  9.  
  10. #if    MEGAMAX & ST520
  11. overlay    "termio"
  12. #endif
  13.  
  14. #if     AMIGA
  15. #define NEW 1006
  16. #define AMG_MAXBUF      1024L
  17. static long terminal;
  18. static char     scrn_tmp[AMG_MAXBUF+1];
  19. static long     scrn_tmp_p = 0;
  20. #endif
  21.  
  22. #if ST520
  23. #include <osbind.h>
  24.     int STscancode = 0;    
  25. #endif
  26.  
  27. #if     VMS
  28. #include        <stsdef.h>
  29. #include        <ssdef.h>
  30. #include        <descrip.h>
  31. #include        <iodef.h>
  32. #include        <ttdef.h>
  33. #include    <tt2def.h>
  34.  
  35. #define NIBUF   128                     /* Input buffer size            */
  36. #define NOBUF   1024                    /* MM says bug buffers win!     */
  37. #define EFN     0                       /* Event flag                   */
  38.  
  39. char    obuf[NOBUF];                    /* Output buffer                */
  40. int     nobuf;                  /* # of bytes in above    */
  41. char    ibuf[NIBUF];                    /* Input buffer          */
  42. int     nibuf;                  /* # of bytes in above  */
  43. int     ibufi;                  /* Read index                   */
  44. int     oldmode[3];                     /* Old TTY mode bits            */
  45. int     newmode[3];                     /* New TTY mode bits            */
  46. short   iochan;                  /* TTY I/O channel             */
  47. #endif
  48.  
  49. #if     CPM
  50. #include        <bdos.h>
  51. #endif
  52.  
  53. #if     MSDOS & (LATTICE | MSC | AZTEC | MWC86)
  54. union REGS rg;        /* cpu register for use of DOS calls */
  55. int nxtchar = -1;    /* character held from type ahead    */
  56. #endif
  57.  
  58. #if RAINBOW
  59. #include "rainbow.h"
  60. #endif
  61.  
  62. #if    USG            /* System V */
  63. #include    <signal.h>
  64. #include    <termio.h>
  65. struct    termio    otermio;    /* original terminal characteristics */
  66. struct    termio    ntermio;    /* charactoristics to use inside */
  67. #endif
  68.  
  69. #if V7 | BSD
  70. #undef    CTRL
  71. #include        <sgtty.h>        /* for stty/gtty functions */
  72. #include    <signal.h>
  73. struct  sgttyb  ostate;          /* saved tty state */
  74. struct  sgttyb  nstate;          /* values for editor mode */
  75. struct tchars    otchars;    /* Saved terminal special character set */
  76. struct tchars    ntchars = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  77.                 /* A lot of nothing */
  78. #if BSD
  79. #include <sys/ioctl.h>        /* to get at the typeahead */
  80. extern    int rtfrmshell();    /* return from suspended shell */
  81. #define    TBUFSIZ    128
  82. char tobuf[TBUFSIZ];        /* terminal output buffer */
  83. #endif
  84. #endif
  85.  
  86. /*
  87.  * This function is called once to set up the terminal device streams.
  88.  * On VMS, it translates TT until it finds the terminal, then assigns
  89.  * a channel to it and sets it raw. On CPM it is a no-op.
  90.  */
  91. ttopen()
  92. {
  93. #if     AMIGA
  94.         terminal = Open("RAW:1/1/639/199/MicroEMACS 3.7/Amiga", NEW);
  95. #endif
  96. #if     VMS
  97.         struct  dsc$descriptor  idsc;
  98.         struct  dsc$descriptor  odsc;
  99.         char    oname[40];
  100.         int     iosb[2];
  101.         int     status;
  102.  
  103.         odsc.dsc$a_pointer = "TT";
  104.         odsc.dsc$w_length  = strlen(odsc.dsc$a_pointer);
  105.         odsc.dsc$b_dtype        = DSC$K_DTYPE_T;
  106.         odsc.dsc$b_class        = DSC$K_CLASS_S;
  107.         idsc.dsc$b_dtype        = DSC$K_DTYPE_T;
  108.         idsc.dsc$b_class        = DSC$K_CLASS_S;
  109.         do {
  110.                 idsc.dsc$a_pointer = odsc.dsc$a_pointer;
  111.                 idsc.dsc$w_length  = odsc.dsc$w_length;
  112.                 odsc.dsc$a_pointer = &oname[0];
  113.                 odsc.dsc$w_length  = sizeof(oname);
  114.                 status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc);
  115.                 if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
  116.                         exit(status);
  117.                 if (oname[0] == 0x1B) {
  118.                         odsc.dsc$a_pointer += 4;
  119.                         odsc.dsc$w_length  -= 4;
  120.                 }
  121.         } while (status == SS$_NORMAL);
  122.         status = SYS$ASSIGN(&odsc, &iochan, 0, 0);
  123.         if (status != SS$_NORMAL)
  124.                 exit(status);
  125.         status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
  126.                           oldmode, sizeof(oldmode), 0, 0, 0, 0);
  127.         if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  128.                 exit(status);
  129.         newmode[0] = oldmode[0];
  130.         newmode[1] = oldmode[1] | TT$M_NOECHO;
  131.         newmode[1] &= ~(TT$M_TTSYNC|TT$M_HOSTSYNC);
  132.         newmode[2] = oldmode[2] | TT2$M_PASTHRU;
  133.         status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  134.                           newmode, sizeof(newmode), 0, 0, 0, 0);
  135.         if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  136.                 exit(status);
  137.         term.t_nrow = (newmode[1]>>24) - 1;
  138.         term.t_ncol = newmode[0]>>16;
  139.  
  140. #endif
  141. #if     CPM
  142. #endif
  143.  
  144. #if     MSDOS & (HP150 == 0) & LATTICE
  145.     /* kill the ctrl-break interupt */
  146.     rg.h.ah = 0x33;        /* control-break check dos call */
  147.     rg.h.al = 1;        /* set the current state */
  148.     rg.h.dl = 0;        /* set it OFF */
  149.     intdos(&rg, &rg);    /* go for it! */
  150. #endif
  151.  
  152. #if    USG
  153.     ioctl(0, TCGETA, &otermio);    /* save old settings */
  154.     ntermio.c_iflag = 0;        /* setup new settings */
  155.     ntermio.c_oflag = 0;
  156.     ntermio.c_cflag = otermio.c_cflag;
  157.     ntermio.c_lflag = 0;
  158.     ntermio.c_line = otermio.c_line;
  159.     ntermio.c_cc[VMIN] = 1;
  160.     ntermio.c_cc[VTIME] = 0;
  161.     ioctl(0, TCSETA, &ntermio);    /* and activate them */
  162. #endif
  163.  
  164. #if     V7 | BSD
  165.         gtty(0, &ostate);                       /* save old state */
  166.         gtty(0, &nstate);                       /* get base of new state */
  167.         nstate.sg_flags |= RAW;
  168.         nstate.sg_flags &= ~(ECHO|CRMOD);       /* no echo for now... */
  169.         stty(0, &nstate);                       /* set mode */
  170.     ioctl(0, TIOCGETC, &otchars);        /* Save old characters */
  171.     ioctl(0, TIOCSETC, &ntchars);        /* Place new character into K */
  172. #if    BSD
  173.     /* provide a smaller terminal output buffer so that
  174.        the type ahead detection works better (more often) */
  175.     setbuffer(stdout, &tobuf[0], TBUFSIZ);
  176.     signal(SIGTSTP,SIG_DFL);    /* set signals so that we can */
  177.     signal(SIGCONT,rtfrmshell);    /* suspend & restart emacs */
  178. #endif
  179. #endif
  180.     /* on all screens we are not sure of the initial position
  181.        of the cursor                    */
  182.     ttrow = 999;
  183.     ttcol = 999;
  184. }
  185.  
  186. /*
  187.  * This function gets called just before we go back home to the command
  188.  * interpreter. On VMS it puts the terminal back in a reasonable state.
  189.  * Another no-operation on CPM.
  190.  */
  191. ttclose()
  192. {
  193. #if     AMIGA
  194.         amg_flush();
  195.         Close(terminal);
  196. #endif
  197. #if     VMS
  198.         int     status;
  199.         int     iosb[1];
  200.  
  201.         ttflush();
  202.         status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  203.                  oldmode, sizeof(oldmode), 0, 0, 0, 0);
  204.         if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  205.                 exit(status);
  206.         status = SYS$DASSGN(iochan);
  207.         if (status != SS$_NORMAL)
  208.                 exit(status);
  209. #endif
  210. #if     CPM
  211. #endif
  212. #if     MSDOS & (HP150 == 0) & LATTICE
  213.     /* restore the ctrl-break interupt */
  214.     rg.h.ah = 0x33;        /* control-break check dos call */
  215.     rg.h.al = 1;        /* set the current state */
  216.     rg.h.dl = 1;        /* set it ON */
  217.     intdos(&rg, &rg);    /* go for it! */
  218. #endif
  219.  
  220. #if    USG
  221.     ioctl(0, TCSETA, &otermio);    /* restore terminal settings */
  222. #endif
  223.  
  224. #if     V7 | BSD
  225.         stty(0, &ostate);
  226.     ioctl(0, TIOCSETC, &otchars);    /* Place old character into K */
  227. #endif
  228. }
  229.  
  230. /*
  231.  * Write a character to the display. On VMS, terminal output is buffered, and
  232.  * we just put the characters in the big array, after checking for overflow.
  233.  * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
  234.  * MS-DOS (use the very very raw console output routine).
  235.  */
  236. ttputc(c)
  237. #if     AMIGA | ST520
  238.         char c;
  239. #endif
  240. {
  241. #if     AMIGA
  242.         scrn_tmp[scrn_tmp_p++] = c;
  243.         if(scrn_tmp_p>=AMG_MAXBUF)
  244.                 amg_flush();
  245. #endif
  246. #if    ST520
  247.     Bconout(2,c);
  248. #endif
  249. #if     VMS
  250.         if (nobuf >= NOBUF)
  251.                 ttflush();
  252.         obuf[nobuf++] = c;
  253. #endif
  254.  
  255. #if     CPM
  256.         bios(BCONOUT, c, 0);
  257. #endif
  258.  
  259. #if     MSDOS & MWC86
  260.         putcnb(c);
  261. #endif
  262.  
  263. #if    MSDOS & (LATTICE | AZTEC) & ~IBMPC
  264.     bdos(6, c, 0);
  265. #endif
  266.  
  267. #if RAINBOW
  268.         Put_Char(c);                    /* fast video */
  269. #endif
  270.  
  271.  
  272. #if     V7 | USG | BSD
  273.         fputc(c, stdout);
  274. #endif
  275. }
  276.  
  277. #if    AMIGA
  278. amg_flush()
  279. {
  280.         if(scrn_tmp_p)
  281.                 Write(terminal,scrn_tmp,scrn_tmp_p);
  282.         scrn_tmp_p = 0;
  283. }
  284. #endif
  285.  
  286. /*
  287.  * Flush terminal buffer. Does real work where the terminal output is buffered
  288.  * up. A no-operation on systems where byte at a time terminal I/O is done.
  289.  */
  290. ttflush()
  291. {
  292. #if     AMIGA
  293.         amg_flush();
  294. #endif
  295. #if     VMS
  296.         int     status;
  297.         int     iosb[2];
  298.  
  299.         status = SS$_NORMAL;
  300.         if (nobuf != 0) {
  301.                 status = SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT,
  302.                          iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0);
  303.                 if (status == SS$_NORMAL)
  304.                         status = iosb[0] & 0xFFFF;
  305.                 nobuf = 0;
  306.         }
  307.         return (status);
  308. #endif
  309.  
  310. #if     CPM
  311. #endif
  312.  
  313. #if     MSDOS
  314. #endif
  315.  
  316. #if     V7 | USG | BSD
  317.         fflush(stdout);
  318. #endif
  319. }
  320.  
  321. /*
  322.  * Read a character from the terminal, performing no editing and doing no echo
  323.  * at all. More complex in VMS that almost anyplace else, which figures. Very
  324.  * simple on CPM, because the system can do exactly what you want.
  325.  */
  326. ttgetc()
  327. {
  328. #if     AMIGA
  329.         char ch;
  330.         amg_flush();
  331.         Read(terminal, &ch, 1L);
  332.         return(255 & (int)ch);
  333. #endif
  334. #if    ST520
  335.     long ch;
  336. /*
  337.  * blink the cursor only if nothing is happening, this keeps the
  338.  * cursor on steadily during movement making it easier to track
  339.  */
  340.     STcurblink(TRUE);  /* the cursor blinks while we wait */
  341.     ch = Bconin(2);
  342.     STcurblink(FALSE); /* the cursor is steady while we work */
  343.     STscancode = (ch >> 16) & 0xff;
  344.            return(255 & (int)ch);
  345. #endif
  346. #if     VMS
  347.         int     status;
  348.         int     iosb[2];
  349.         int     term[2];
  350.  
  351.         while (ibufi >= nibuf) {
  352.                 ibufi = 0;
  353.                 term[0] = 0;
  354.                 term[1] = 0;
  355.                 status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
  356.                          iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
  357.                 if (status != SS$_NORMAL)
  358.                         exit(status);
  359.                 status = iosb[0] & 0xFFFF;
  360.                 if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
  361.                         exit(status);
  362.                 nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  363.                 if (nibuf == 0) {
  364.                         status = SYS$QIOW(EFN, iochan, IO$_READLBLK,
  365.                                  iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
  366.                         if (status != SS$_NORMAL
  367.                         || (status = (iosb[0]&0xFFFF)) != SS$_NORMAL)
  368.                                 exit(status);
  369.                         nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  370.                 }
  371.         }
  372.         return (ibuf[ibufi++] & 0xFF);    /* Allow multinational  */
  373. #endif
  374.  
  375. #if     CPM
  376.         return (biosb(BCONIN, 0, 0));
  377. #endif
  378.  
  379. #if RAINBOW
  380.         int Ch;
  381.  
  382.         while ((Ch = Read_Keyboard()) < 0);
  383.  
  384.         if ((Ch & Function_Key) == 0)
  385.                 if (!((Ch & 0xFF) == 015 || (Ch & 0xFF) == 0177))
  386.                         Ch &= 0xFF;
  387.  
  388.         return Ch;
  389. #endif
  390.  
  391. #if     MSDOS & MWC86
  392.         return (getcnb());
  393. #endif
  394.  
  395. #if    MSDOS & (LATTICE | MSC | AZTEC)
  396.     int c;        /* character read */
  397.  
  398.     /* if a char already is ready, return it */
  399.     if (nxtchar >= 0) {
  400.         c = nxtchar;
  401.         nxtchar = -1;
  402.         return(c);
  403.     }
  404.  
  405.     /* call the dos to get a char */
  406.     rg.h.ah = 7;        /* dos Direct Console Input call */
  407.     intdos(&rg, &rg);
  408.     c = rg.h.al;        /* grab the char */
  409.     return(c & 255);
  410. #endif
  411.  
  412. #if     V7 | USG | BSD
  413.         return(127 & fgetc(stdin));
  414. #endif
  415. }
  416.  
  417. #if    TYPEAH
  418. /* typahead:    Check to see if any characters are already in the
  419.         keyboard buffer
  420. */
  421.  
  422. typahead()
  423.  
  424. {
  425. #if    MSDOS & (LATTICE | AZTEC | MWC86)
  426.     int c;        /* character read */
  427.     int flags;    /* cpu flags from dos call */
  428.  
  429. #if    MSC
  430.     if (kbhit() != 0)
  431.         return(TRUE);
  432.     else
  433.         return(FALSE);
  434. #endif
  435.  
  436.     if (nxtchar >= 0)
  437.         return(TRUE);
  438.  
  439.     rg.h.ah = 6;    /* Direct Console I/O call */
  440.     rg.h.dl = 255;    /*         does console input */
  441. #if    LATTICE | AZTEC
  442.     flags = intdos(&rg, &rg);
  443. #else
  444.     intcall(&rg, &rg, 0x21);
  445.     flags = rg.x.flags;
  446. #endif
  447.     c = rg.h.al;    /* grab the character */
  448.  
  449.     /* no character pending */
  450.     if ((flags & 64) != 0)
  451.         return(FALSE);
  452.  
  453.     /* save the character and return true */
  454.     nxtchar = c;
  455.     return(TRUE);
  456. #endif
  457.  
  458. #if    BSD
  459.     int x;    /* holds # of pending chars */
  460.  
  461.     return((ioctl(0,FIONREAD,&x) < 0) ? 0 : x);
  462. #endif
  463.     return(FALSE);
  464. }
  465. #endif
  466.  
  467.